/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.dafe.partyband.mediaplayer;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javazoom.jlgui.basicplayer.*;
import org.dafe.partyband.db.api.DbManager;
import org.dafe.partyband.db.api.ISong;
import org.dafe.partyband.db.api.ISongResource;
import org.dafe.partyband.db.api.handlers.ISongResourceHandler;
import org.dafe.partyband.importer.api.ResourceTypeUtils;
import org.dafe.partyband.services.api.IDurationObtainer;
import org.openide.util.Exceptions;
import org.openide.util.lookup.ServiceProvider;
    

/**
 *
 * @author dafe
 */
@ServiceProvider(service=IDurationObtainer.class)
public class JavaZoomDurationObtainer implements IDurationObtainer, BasicPlayerListener {

    private static final ISongResourceHandler resHandler = DbManager.getBandManager().getHandlersLookup().lookup(ISongResourceHandler.class);
    
    private static final Logger LOG = Logger.getLogger(JavaZoomDurationObtainer.class.getName());
    
    private final BasicPlayer playerForDuration;
    private final Map<ISong, Integer> durationsCache;
    private int curDuration = -1;

    public JavaZoomDurationObtainer() {
        playerForDuration = new BasicPlayer();
        playerForDuration.addBasicPlayerListener(this);
        durationsCache = new HashMap<ISong, Integer>();
    }

    public int getDuration(ISong song) {
        try {
            // temporary for testing threading
            Thread.sleep(500);
        } catch (InterruptedException ex) {
            // well ok, that may happen...
        }
        
        // try cache first
        Integer cachedDuration = durationsCache.get(song);
        if (cachedDuration != null) {
            return cachedDuration;
        }
        
        ISongResource songAudioRes = ResourceTypeUtils.getMp3(song);
        if (songAudioRes != null) {
            File tempFile;
            try {
                tempFile = File.createTempFile("partyband", songAudioRes.getFileName());
            } catch (IOException ex) {
                LOG.log(Level.INFO, "Unable to create temp file for song " + song.getName(), ex);
                return -1;
            }
            String origPath = songAudioRes.getFilePath();
            songAudioRes.setFilePath(tempFile.getPath());
            resHandler.exportFromDbToFile(songAudioRes);
            songAudioRes.setFilePath(origPath);
            try {
                playerForDuration.open(tempFile);
            } catch (Exception ex) {
                LOG.log(Level.INFO, "Sound file probably corrupted for song " + song.getName(), ex);
                return -1;
            }
            // calling playerForDuration.open(..) above will trigger
            // opened(...) method which sets curDuration
            if (curDuration > 0) {
                durationsCache.put(song, Integer.valueOf(curDuration));
            }
            return curDuration;
        }
        
        return -1;
    }

    public void opened(Object stream, Map properties) {
        curDuration = JavaZoomUtils.obtainDuration(stream, properties);
    }

    public void progress(int bytesread, long microseconds, byte[] pcmdata, Map properties) {
    }

    public void stateUpdated(BasicPlayerEvent event) {
    }

    public void setController(BasicController controller) {
    }
    
}
